<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		
		<style>
			ul li {
				list-style-type: none;
			}
		</style>
		 
	</head>
	<body>
		<ul id="for">
		    <li v-for="item in items">
		       $index). Parent.name:{{name}}; item: {{item.id}}, text:
		      <span v-for="t in item.text">{{t.txt}}</span>
		    </li>
		</ul>
		
		<script>
			
			var slice = Array.prototype.slice;
			
			var model = {
							name: 'model',
							items : [
								        {id: '10000', text: [{txt: 'start'}, {txt: ',10000,'}, {txt: 'end'}]},
								        {id: '10001', text: [{txt: 'start'}, {txt: ',10001,'}, {txt: 'end'}]},
								        {id: '10002', text: [{txt: 'start'}, {txt: ',10002,'}, {txt: 'end'}]},
		      						]
					    }
			
			var forNode = document.getElementById('for');
			
			compile(forNode, model);
			
			function compile(node, scope) {
				switch(node.nodeType) {
					// node节点
					case 1:
						compileChild(node, scope);
						break;
					// text文本
					case 3:						
//						console.log(node.nodeValue);
						break;
					default:
				}
			}
			
			function compileChild(node, scope) {
				var childNodes = node.childNodes;
				if(childNodes) {
					slice.call(childNodes).forEach(function(currentNode, index) {
						var attrs = currentNode.attributes;
						
						if(isForDir(attrs)) {
							dealForNode(currentNode, scope);
						}else {
							compile(currentNode, scope);
						}
					})
				}
			}
			
			function isForDir(attrs) {
				var isFor = false;
				if(attrs) {
					slice.call(attrs).forEach(function(currentAttr, index) {
						if(currentAttr.name.indexOf('v-for') > -1) {
							isFor = true;
						}
					})
				}else {
					isFor = false;
				}
				return isFor;
			}
			
			function dealForNode(node, scope) {
				
				var exp, currentNodeValue;
				
				var items = node.getAttribute('v-for').split('in')[1].trim().split('.');
				var item  = node.getAttribute('v-for').split('in')[0].trim();
				
				var parentNode = node.parentNode;
				parentNode.removeChild(node);
				
				var length = typeof items == 'string' ? 1 : items.length;
				var items = items[length - 1];
				
				slice.call(scope[items]).forEach(function(currentScope, index) {
					var cloneNode = node.cloneNode(true);
					parentNode.appendChild(cloneNode);
					
					model[item]  = currentScope;
					model['index'] = index + 1;
					currentNodeValue = cloneNode.firstChild.nodeValue;
					cloneNode.firstChild.nodeValue = computeExpression(currentNodeValue, model);
					
					compile(cloneNode, currentScope);
				})
			}
			
			function computeExpression(exp, scope) {
				var regExp  = /\{\{\s*(.+?)\s*\}\}/g,
					regOnly = /^\{\{\s*(.+?)\s*\}\}$/g,
					res;
				
				res = exp.replace(regExp, function(match, every, index, exp) {
					if(regOnly.test(exp)) {
						return every || '';
					}else {
						return '"+' + every + '+"';
					}
				});
				
				res = res.replace(/\$(index+?)/g, function(match, every, index, exp) {
					return '"+' + every + '+"';
				})
				
				if(/[\"]/.test(res)) {
					res = '"' + res.trim() + '"';
				}
				
				try {
					with(scope) {
						return eval(res);
					}
				}catch(err) {
					console.warn(err);
				}
			}
			
		</script>
	</body>
</html>
